package br.com.iswe.gerador.velocity.gerador;

import java.io.File;
import java.io.FileWriter;
import java.io.Writer;

import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;

import br.com.iswe.gerador.velocity.info.InfoEntidadeImpl;
import br.com.iswe.gerador.velocity.info.InfoGerador;

public class GeradorFacade extends GeradorBase {

	private static final String FACADE_ABSTRACT_JAVA = "FacadeAbstract.java";

    private static final String FACADE_ABSTRACT_VM = "FACADE-ABSTRACT.vm";

    private static final String FACADE_INTERFACE_VM = "FACADE-INTERFACE.vm";

    private static final String FACADE_IMPL_VM = "FACADE-IMPL.vm";

    private static final String FACADE_JAVA = "Facade.java";

    private static final String FACADE_IMPL_JAVA = "FacadeImpl.java";

    private static final String GERADOR_BO_PASTA_SAIDA = "gerador.facade.pasta.saida";

	private static final String PACOTE_FACADE = "PacoteFacade";

	public static final String GERADOR_FACADE_PACKAGE_TO = "gerador.facade.package.to";

	public static final String GERADOR_FACADE_PACKAGE_FROM = "gerador.facade.package.from";

	public static final String NOME_GERADOR = "geradorFacade";

	private InfoGerador infoGerador;

	public void gerarCodigo(InfoEntidadeImpl info) throws Exception {
		Template template = null;
		Writer wrt = null;
		String arquivoSaida = null;
		
		//Obtem o pacote para objetos abstratos
        String pacoteAbstrato = infoGerador.getPacoteAbstratos();
		// Primeiro Passo : Cria o contexto com as informa��es necess�rias para
		// criar a classe de BO.
		VelocityContext ctx = buildContext(this.infoGerador);
		// Obt�m o Pakage do componente :
		String pakg = info.getReplacePackage(GERADOR_FACADE_PACKAGE_FROM, GERADOR_FACADE_PACKAGE_TO);
		ctx.put(PACOTE_FACADE, pakg);
		// Adiciona a info da entidade
		ctx.put(InfoEntidadeImpl.NOME_INFO, info);

		// Segundo Passo : Obt�m o diret�rio onde ser� gerado o fonte de sa�da.
		String basePath = infoGerador.getPastaBaseSaida() + SEPARADOR
				+ infoGerador.getPropriedade(GERADOR_BO_PASTA_SAIDA);
		File pathSaida = new File(basePath + SEPARADOR
				+ infoGerador.getPathFromPackage(pakg));
		// Verifica se o path ja existe
		if (!pathSaida.exists()) {
			pathSaida.mkdirs();
		}

        //verifica se existe a pasta de abstratos
        File pastaAbstratos = new File(pathSaida.getAbsolutePath() + SEPARADOR + pacoteAbstrato);
        if(!pastaAbstratos.exists()){
            pastaAbstratos.mkdirs();
        }
        
		// Terceiro Passo : Verifica se a classe implementada do BO j� est�
		// criada. Se estiver, aborta a gera��o da classe implementada
		arquivoSaida = pathSaida.getAbsolutePath() + SEPARADOR + info.getNomeEntidade1() + FACADE_IMPL_JAVA;
        if( infoGerador.shouldGenerateFile(arquivoSaida) ){
			
        	System.out.println("Generating File: " + arquivoSaida);
        	
        	// Quarto Passo : Obt�m o Template da Facade e gera a sa�da.
			// Gerando a classe de implementacao da Facade
			template = Velocity.getTemplate(FACADE_IMPL_VM);
			// Escreve o arquivo de sa�da
			wrt = new FileWriter(arquivoSaida);
			// Gera o documento.
			template.merge(ctx, wrt);
			// Descarrega para o disco.
			wrt.flush();
			wrt.close();
		}
        
        arquivoSaida = pathSaida.getAbsolutePath() + SEPARADOR + info.getNomeEntidade1() + FACADE_JAVA;
        if( infoGerador.shouldGenerateFile(arquivoSaida) ){
            
        	System.out.println("Generating File: " + arquivoSaida);
        	// Gerando a interface da Facade
    		template = Velocity.getTemplate(FACADE_INTERFACE_VM);
    		// Escreve o arquivo de sa�da
    		wrt = new FileWriter(arquivoSaida);
    		// Gera o documento.
    		template.merge(ctx, wrt);
    		// Descarrega para o disco.
    		wrt.flush();
    		wrt.close();
        }
        
        arquivoSaida = pastaAbstratos.getAbsolutePath() + SEPARADOR + info.getNomeEntidade1() + FACADE_ABSTRACT_JAVA;
        if( infoGerador.shouldGenerateFile(arquivoSaida) ){
        	System.out.println("Generating File: " + arquivoSaida);
        	// Gerando a classe abstrada da Facade
	        template = Velocity.getTemplate(FACADE_ABSTRACT_VM);
	        // Escreve o arquivo de sa�da
	        wrt = new FileWriter(arquivoSaida);
	        // Gera o documento.
	        template.merge(ctx, wrt);
	        // Descarrega para o disco.
	        wrt.flush();
	        wrt.close();
        }
	}

	public void inicio(InfoGerador infoGerador) {
		this.infoGerador = infoGerador;
	}

	public void fim() {
		this.infoGerador = null;
	}
}
